'use strict';

// cloudfunctions/batch-upload/index.js
const db = uniCloud.database();

async function uploadImages(imgDirRoot, category, batchSize = 50, requiredImages) {
  const fs = require('fs');
  const path = require('path');
  
  const categoryImgDir = path.join(imgDirRoot, category);
  const files = fs.readdirSync(categoryImgDir);
  const filesToUpload = Array.isArray(files)
    ? files.filter(name => !requiredImages || requiredImages.has(name))
    : [];
  
  const fileIdMap = {};
  
  // 分批上传图片（客户端直传的配套云函数也支持，保持一致）
  for (let i = 0; i < filesToUpload.length; i += batchSize) {
    const batchFiles = filesToUpload.slice(i, i + batchSize);
    const uploadPromises = batchFiles.map(filename => {
      const filePath = path.join(categoryImgDir, filename);
      return uniCloud.uploadFile({
        cloudPath: `dishes/${category}/${filename}`,
        fileContent: fs.createReadStream(filePath)
      });
    });
    
    const batchResults = await Promise.allSettled(uploadPromises);
    batchResults.forEach((res, idx) => {
      const filename = batchFiles[idx];
      if (res.status === 'fulfilled' && res.value && (res.value.fileID || res.value.fileId)) {
        fileIdMap[filename] = res.value.fileID || res.value.fileId;
      } else {
        console.error(`[${category}] 上传失败: ${filename}`, res.reason || res);
      }
    });
    
    console.log(`已上传图片: ${i + batchFiles.length}/${filesToUpload.length}`);
  }
  
  return fileIdMap;
}

async function uploadDishRecords(jsonData, category, fileIdMap) {
  const collection = db.collection('dishes');
  
  // 为每条记录添加分类信息和完整的云存储路径
  const records = jsonData.map(item => ({
    chineseName: item.chineseName,
    dishName: item.dishName,
    dishIngredient: item.dishIngredient,
    category: category,
    img: fileIdMap && item.img ? (fileIdMap[item.img] || `dishes/${category}/${item.img}`) : `dishes/${category}/${item.img}`,
    createDate: Date.now()
  }));
  
  // 分批插入数据库，每批100条
  const batchSize = 100;
  let successCount = 0;
  
  for (let i = 0; i < records.length; i += batchSize) {
    const batch = records.slice(i, i + batchSize);
    try {
      await collection.add(batch);
      successCount += batch.length;
      console.log(`已插入记录: ${successCount}/${records.length}`);
    } catch (error) {
      console.error(`插入批次 ${i} 失败:`, error);
    }
  }
  
  return successCount;
}

async function insertDishRecords(records) {
  const collection = db.collection('dishes');
  const batchSize = 100;
  let successCount = 0;

  for (let i = 0; i < records.length; i += batchSize) {
    const batch = records.slice(i, i + batchSize);
    try {
      await collection.add(batch);
      successCount += batch.length;
      console.log(`入库记录: ${successCount}/${records.length}`);
    } catch (error) {
      console.error(`入库批次 ${i} 失败:`, error);
    }
  }

  return successCount;
}

exports.main = async (event, context) => {
  const { action, category, jsonDirRoot, imgDirRoot } = event;
  
  if (action === 'upload-category') {
    try {
      // 1. 读取JSON文件
      const fs = require('fs');
      const path = require('path');
      const jsonPath = path.join(jsonDirRoot, `${category}.json`);
      const jsonData = JSON.parse(fs.readFileSync(jsonPath, 'utf8'));
      
      // 2. 上传图片到云存储（仅上传JSON引用的图片）
      console.log(`开始上传 ${category} 的图片...`);
      const required = new Set(Array.isArray(jsonData) ? jsonData.map(item => item.img).filter(Boolean) : []);
      const fileIdMap = await uploadImages(imgDirRoot, category, 50, required);
      
      // 3. 上传记录到数据库，img 存储 fileID 或 cloudPath
      console.log(`开始上传 ${category} 的记录...`);
      const count = await uploadDishRecords(jsonData, category, fileIdMap);
      
      return {
        success: true,
        message: `成功上传 ${category} 类别，共 ${count} 条记录`
      };
    } catch (error) {
      return {
        success: false,
        error: error.message
      };
    }
  }
  
  if (action === 'insert-records') {
    try {
      const { records } = event;
      if (!Array.isArray(records) || records.length === 0) {
        return { success: false, message: 'records 为空' };
      }
      const count = await insertDishRecords(records);
      return { success: true, message: `成功入库 ${count} 条记录`, count };
    } catch (error) {
      return { success: false, error: error.message };
    }
  }

  // 覆盖写入：按四个字段完全相同（chineseName, dishName, dishIngredient, img）匹配则更新，否则新增
  if (action === 'upsert-records') {
    try {
      const { records } = event;
      if (!Array.isArray(records) || records.length === 0) {
        return { success: false, message: 'records 为空' };
      }

      const collection = db.collection('dishes');
      let updated = 0;
      let inserted = 0;

      for (const rec of records) {
        const { chineseName, dishName, dishIngredient, category } = rec;
        // 匹配条件：按 chineseName + dishName + dishIngredient + category 四字段匹配
        const exist = await collection
          .where({ chineseName, dishName, dishIngredient, category })
          .get();
        const list = Array.isArray(exist.data) ? exist.data : [];
        if (list.length > 0) {
          // 匹配到现有记录：覆盖更新所有匹配项
          for (const row of list) {
            const id = row._id;
            try {
              await collection.doc(id).update(rec);
              updated += 1;
            } catch (e) {
              console.error('更新失败：', id, e);
            }
          }
        } else {
          try {
            await collection.add(rec);
            inserted += 1;
          } catch (e) {
            console.error('新增失败：', e);
          }
        }
      }

      return { success: true, updated, inserted, count: updated + inserted };
    } catch (error) {
      return { success: false, error: error.message };
    }
  }

  // 按分页拉取 dishes 记录（仅返回 _id 与 img），用于前端按页校验/修复
  if (action === 'list-dishes') {
    try {
      const collection = db.collection('dishes');
      const PAGE_SIZE = Number(event.pageSize) || 200;
      let cursor = Number(event.cursor) || 0;

      const whereCond = event.category ? { category: event.category } : {};
      const page = await collection
        .where(whereCond)
        .field({ _id: true, img: true })
        .limit(PAGE_SIZE)
        .skip(cursor)
        .get();
      const items = Array.isArray(page.data) ? page.data : [];
      const nextCursor = cursor + items.length;
      const hasMore = items.length === PAGE_SIZE;
      return { success: true, items, nextCursor, hasMore };
    } catch (error) {
      return { success: false, error: error.message };
    }
  }

  // 更新指定记录的图片 fileID（修复缺失图片后写回）
  if (action === 'update-image-by-id') {
    try {
      const id = event.id;
      const img = event.img;
      if (!id || typeof id !== 'string') {
        return { success: false, message: 'id 无效' };
      }
      if (!img || (typeof img !== 'string' && typeof img !== 'object')) {
        return { success: false, message: 'img 无效' };
      }
      const collection = db.collection('dishes');
      await collection.doc(id).update({ img });
      return { success: true, id, img };
    } catch (error) {
      return { success: false, error: error.message };
    }
  }

  if (action === 'delete-all') {
    try {
      const collection = db.collection('dishes');
      const PAGE_SIZE = 500;
      const FILE_DELETE_BATCH = 100;
      let deletedRecords = 0;
      let deletedFiles = 0;
      while (true) {
        const page = await collection.limit(PAGE_SIZE).get();
        const records = Array.isArray(page.data) ? page.data : [];
        if (records.length === 0) break;

        // 去重：同一文件可能被多条记录引用，删除前去重可减少无效调用
        const fileList = Array.from(new Set(
          records
            .map(r => (typeof r.img === 'string' ? r.img.trim() : r.img))
            .filter(Boolean)
        ));
        for (let i = 0; i < fileList.length; i += FILE_DELETE_BATCH) {
          const batch = fileList.slice(i, i + FILE_DELETE_BATCH);
          try {
            const delRes = await uniCloud.deleteFile({ fileList: batch });
            if (delRes && Array.isArray(delRes.fileList)) {
              const successCount = delRes.fileList.length;
              console.log(`成功删除图片 ${successCount} 条`);
              deletedFiles += successCount
            } else {
              deletedFiles += batch.length;
            }
          } catch (e) {
            console.error('删除云存储文件失败：', e);
          }
        }

        const ids = records.map(r => r._id).filter(Boolean);
        const results = await Promise.allSettled(ids.map(id => collection.doc(id).remove()));
        deletedRecords += results.filter(r => r.status === 'fulfilled').length;

        await new Promise(resolve => setTimeout(resolve, 200));
      }

      return { success: true, deletedFiles, deletedRecords };
    } catch (error) {
      return { success: false, error: error.message };
    }
  }

  // 删除指定时间之后的记录与对应图片
  if (action === 'delete-after') {
    try {
      const cutoffTs = Number(event.cutoffTs);
      if (!cutoffTs || !Number.isFinite(cutoffTs)) {
        return { success: false, message: 'cutoffTs 无效' };
      }

      const collection = db.collection('dishes');
      const dbCmd = db.command;
      // 仅按 createDate 进行时间过滤（不再使用 createTime）
      const condition = { createDate: dbCmd.gte(cutoffTs) };

      // 分步处理，避免请求超时：每次仅处理一个分页
      const PAGE_SIZE = Number(event.pageSize) || 200;
      const FILE_DELETE_BATCH = 50;
      // 删除会改变数据集，基于 skip 的游标会失效；始终从头查询当前集合第一页
      const cursor = 0;

      const page = await collection
        .where(condition)
        .orderBy('createDate', 'asc')
        .limit(PAGE_SIZE)
        .skip(0)
        .get();

      const records = Array.isArray(page.data) ? page.data : [];
      let deletedRecords = 0;
      let deletedFiles = 0;

      if (records.length > 0) {
        // 仅删除有效的文件ID：如果 img 是字符串则跳过（视为无效图片）
        const fileList = Array.from(new Set(
          records
            .map(r => {
              const v = r.img;
              if (typeof v === 'string') return null; // 跳过字符串
              if (v && typeof v === 'object') {
                if (typeof v.fileID === 'string') return v.fileID;
                if (typeof v.fileId === 'string') return v.fileId;
              }
              return null;
            })
            .filter(Boolean)
        ));

        for (let i = 0; i < fileList.length; i += FILE_DELETE_BATCH) {
          const batch = fileList.slice(i, i + FILE_DELETE_BATCH);
          try {
            const delRes = await uniCloud.deleteFile({ fileList: batch });
            if (delRes && Array.isArray(delRes.fileList)) {
              deletedFiles += delRes.fileList.length;
            } else {
              deletedFiles += batch.length;
            }
          } catch (e) {
            console.error('删除云存储文件失败：', e);
          }
        }

        const ids = records.map(r => r._id).filter(Boolean);
        const results = await Promise.allSettled(ids.map(id => collection.doc(id).remove()));
        deletedRecords += results.filter(r => r.status === 'fulfilled').length;
      }

      const nextCursor = records.length; // 仅兼容返回，不再应用
      const hasMore = records.length === PAGE_SIZE;
      return { success: true, deletedFiles, deletedRecords, nextCursor, hasMore };
    } catch (error) {
      return { success: false, error: error.message };
    }
  }
  
  // 统计：dishes 表记录总数与唯一图片数量（以记录中的 img 字段去重统计）
  if (action === 'querydishes') {
    try {
      const PAGE_SIZE = Number(event.pageSize) || 200; // 每次处理条数

      const collection = db.collection('dishes');
      let totalRecords = 0;
      try {
        const countRes = await collection.where({}).count();
        totalRecords = (countRes && (countRes.total || (countRes.result && countRes.result.total))) || 0;
      } catch (e) {
        // 回退：分页统计条数（兼容环境不支持count的情况）
        let skip = 0;
        while (true) {
          const page = await collection.field('_id').limit(PAGE_SIZE).skip(skip).get();
          const len = Array.isArray(page.data) ? page.data.length : 0;
          totalRecords += len;
          if (len < PAGE_SIZE) break;
          skip += len;
        }
      }
      return { success: true, totalRecords};
    } catch (error) {
      return { success: false, error: error.message };
    }
  }

  if (action === 'queryimgs') {
    try {

      let cursor = Number(event.cursor) || 0; // 本次处理起始偏移
      const PAGE_SIZE = Number(event.pageSize) || 200; // 每次处理条数
      const CHECK_BATCH = Number(event.checkBatch) || 20; // 校验图片存在的批大小

      let totalImages = 0;
      const collection = db.collection('dishes');


      //step 1 分页查询记录（仅获取 img 字段）
      const page = await collection.field({ img: true }).limit(PAGE_SIZE).skip(cursor).get();
      const records = Array.isArray(page.data) ? page.data : [];

      //step 2 本页去重的候选 fileID 列表
      const ids = [];
      const seen = new Set();
      for (const r of records) {
        const v = r.img;
        // 情况二：字符串形式的 fileID，例如 cloud://env-xxxx/xxxx
        if (typeof v === 'string') {
          const fidStr = v.trim();
          if (fidStr && /^cloud:\/\//.test(fidStr) && !seen.has(fidStr)) {
            seen.add(fidStr);
            ids.push(fidStr);
          }
        }
      }
      // const validImages = ids.length;
      // const nextCursor = cursor + records.length;
      // const hasMore = records.length === PAGE_SIZE;
      // console.log(' 本页校验存在的图片数量:', validImages);
      // return { success: true, validImages, nextCursor, hasMore };

      // step 3 校验存在的 fileID（本页）
      const validFileIds = [];
      for (let i = 0; i < ids.length; i += CHECK_BATCH) {
        const batch = ids.slice(i, i + CHECK_BATCH);
        try {
          const res = await uniCloud.getTempFileURL({ fileList: batch });
          const list = (res && Array.isArray(res.fileList)) ? res.fileList
            : (res && Array.isArray(res.urls)) ? res.urls
            : (res && Array.isArray(res.tempFiles)) ? res.tempFiles
            : [];
          for (let j = 0; j < list.length; j++) {
            const it = list[j];
            const hasUrl = (typeof it.tempFileURL === 'string' && it.tempFileURL)
              || (typeof it.download_url === 'string' && it.download_url)
              || (typeof it.url === 'string' && it.url);
            const okCode = (typeof it.code === 'number' && it.code === 0) || it.status === 0 || it.status === 'SUCCESS';
            const idVal = typeof it.fileID === 'string' ? it.fileID
              : typeof it.fileId === 'string' ? it.fileId
              : (Array.isArray(batch) ? batch[j] : null);
            if ((hasUrl || okCode) && idVal) validFileIds.push(idVal);
          }
        } catch (e) {
          // 控制节奏，避免长时间阻塞
          console.error('校验文件是否存在失败：', e);
        }
        await new Promise(resolve => setTimeout(resolve, 100));
      }

      const validImages = validFileIds.length;
      const nextCursor = cursor + records.length;
      const hasMore = records.length === PAGE_SIZE;
      console.log(' 本页校验存在的图片数量:', validImages);
      return { success: true, validImages, nextCursor, hasMore };
    } catch (error) {
      return { success: false, error: error.message };
    }
  }

  // 查询指定中文菜单列表的完整记录
  if (action === 'query-special') {
    try {
      const collection = db.collection('dishes');
      const dbCmd = db.command;
      const specialDishes = Array.isArray(event.specialDishes) && event.specialDishes.length > 0
        ? event.specialDishes
        : ["艾米粿", "艾饺"]; // 默认列表

      // 可能存在多条记录，做分页拉取
      const PAGE_SIZE = 500;
      let skip = 0;
      const items = [];
      while (true) {
        const page = await collection
          .where({ chineseName: dbCmd.in(specialDishes) })
          .limit(PAGE_SIZE)
          .skip(skip)
          .get();
        const data = Array.isArray(page.data) ? page.data : [];
        items.push(...data);
        if (data.length < PAGE_SIZE) break;
        skip += data.length;
      }

      return { success: true, items, total: items.length };
    } catch (error) {
      return { success: false, error: error.message };
    }
  }
  
  return { success: false, message: '未知操作' };
};
